#include <pthread.h>
#include <math.h>

#include "Combat.h"
#include "Boulier.h"
#include "Jeu.h"

using namespace std;

Combat::Combat() {

	nbArmeePerduAttaque = 0;
	nbArmeePerduDefense = 0;
}

Joueur * Combat::getAttaquant() {
	return attaquant;
}

Joueur * Combat::getDefenseur() {
	return defenseur;
}

int Combat::getNbArmeeAttaque() {
	return nbArmeeAttaque;
}

int Combat::getNbArmeeDefense() {
	return nbArmeeDefense;
}

Territoire * Combat::getPaysAttaque() {
	return paysAttaque;
}

Territoire * Combat::getPaysDefense() {
	return paysDefense;
}

void Combat::setAttaquant(Joueur * unAttaquant) {
	attaquant = unAttaquant;
}

void Combat::setDefenseur(Joueur * unDefenseur) {
	defenseur = unDefenseur;
}

void Combat::setNbArmeeAttaque(int nbArmmeeAttaque) {
	this->nbArmeeAttaque = nbArmmeeAttaque;
}

void Combat::setNbArmeeDefense(int nbArmmeeDefense) {
	this->nbArmeeDefense = nbArmmeeDefense;
}

void Combat::setPaysAttaque(Territoire* paysAttaque) {
	this->paysAttaque = paysAttaque;
	//this->attaquant = paysAttaque->getPropretaire();
}

void Combat::setPaysDefense(Territoire* paysDefense) {
	this->paysDefense = paysDefense;
	//this->defenseur = paysDefense->getPropretaire();
}

int Combat::getScoreAttaque() {
	return this->scoreAttaque;
}

int Combat::getScoreDefense() {
	return this->scoreDefense;
}
void Combat::setScoreAttaque(int _score) {
	this->scoreAttaque = _score;
}
void Combat::setScoreDefense(int _score) {
	this->scoreDefense = _score;
}

void triTableau(int *tab, size_t size, int order) {
	size_t i = 0;
	size_t j = 0;

	if (tab != NULL && size > 1) {
		/* Parcours du tableau. */
		for (i = 0; i < size; i++) {
			/* Recherche du minimum. */
			size_t min = i;
			for (j = i; j < size; j++) {
				if (order == 0) {
					if (tab[j] < tab[min]) {
						min = j;
					}
				} else {
					if (tab[j] > tab[min]) {
						min = j;
					}
				}
			}

			/* Echange des valeurs du tableau. */
			{
				int tmp = tab[i];
				tab[i] = tab[min];
				tab[min] = tmp;
			}
		}
	}
}
int min(int val1, int val2) {

	if (val1 <= val2)
		return val1;
	else
		return val2;
}

int max(int val1, int val2) {

	if (val1 >= val2)
		return val1;
	else
		return val2;
}


void Combat::combattre(int tabDeAttaque[3], int tabDeDefense[3]) {

	//******modif   youenn
	this->scoreAttaque=0;
	this->scoreDefense=0;

	int nbAtt=0;
	int nbDef=0;

	for (int t =0; t<3; t++) {
		if (tabDeAttaque[t]!=-1) {
			nbAtt++;
			cout<<"attaque" <<nbAtt<<" : "<<tabDeAttaque[t]<<endl;
		}
	}

	for (int t =0; t<3; t++) {
		if (tabDeDefense[t]!=-1) {
			nbDef++;
			cout<<"defense" <<nbDef<<" : "<<tabDeDefense[t]<<endl;
		}
	}

	//paysDefense->setNbArmee(nbDef);

	int size1 = nbAtt;
	int size2 = nbDef;
	//********
	cout << "taille tab attaque = " << size1 << endl;
	cout << "taille tab defense = " << size2 << endl;

	cout<<"tri les des attaques "<<endl;

	triTableau(tabDeAttaque, size1, 1);
	triTableau(tabDeDefense, size2, 1);

	for (int i = 0; i < size1; i++) {
		cout << "de attaque "<< i << " = " << tabDeAttaque[i] << endl;
	}

	for (int i = 0; i < size2; i++) {
		cout << "de defense "<< i << " = " << tabDeDefense[i] << endl;
	}

	cout<<"comparaison des des tries"<<endl;

	for (int j = 0; j < min(size1, size2); j++) {

		cout<<"Attaque = " << tabDeAttaque[j] <<" Defense = "
				<< tabDeDefense[j]<<endl;

		if (tabDeAttaque[j] > tabDeDefense[j]) {

			cout << "le defenseur perd une arme" << endl;
			nbArmeePerduDefense++;
			this->scoreAttaque++;
			paysDefense->setNbArmee(paysDefense->getNbArmee() - 1);
			defenseur->setNbArmeeTotal(defenseur->getNbArmeeTotal() - 1);
			//******
			paysAttaque->setNbArmee(paysAttaque->getNbArmee() + 1);
			attaquant->setNbArmeeTotal(attaquant->getNbArmeeTotal() + 1);
		}

		else {

			if (tabDeAttaque[j] < tabDeDefense[j]) {

				cout << "l'attaquant perd une arme" << endl;
				nbArmeeAttaque++;
				this->scoreDefense++;
				paysAttaque->setNbArmee(paysAttaque->getNbArmee() - 1);
				//*******
				attaquant->setNbArmeeTotal(attaquant->getNbArmeeTotal() - 1);
				paysDefense->setNbArmee(paysDefense->getNbArmee() + 1);
				defenseur->setNbArmeeTotal(defenseur->getNbArmeeTotal() + 1);
			}
		}

		// Si le pays de defense n'a plus d'armme
		if (paysDefense->getNbArmee() == 0) {

			// le defenseur perd le territoire 
			cout << "le defenseur a perdu son territoire" << endl;
			defenseur->retirerTerritoire(paysDefense);

			// l'attaquant recupere le territoire 
			attaquant->ajouterTerritoire(paysDefense);
			paysDefense->setProprietaire(attaquant);
			paysDefense->setCouleurOrigine(attaquant->couleur);

			// l'attaquant place une armee sur le territoire de defense
			paysDefense->setNbArmee(1);

			// et il enleve une armee sur le territoire d'attaque
			paysAttaque->setNbArmee(paysAttaque->getNbArmee() - 1);

			// Test pour savoir si le contienent possede un proprietaire							
			Jeu* risk = Jeu::getInstance();

			Continent* continent = risk->getContinentByTerritoire(paysDefense);

			Joueur* proprio = continent->getProprietaire(attaquant);

			// Si le continent possede un proprietaire et qu'il s'agit de l'attaquant
			if (proprio != NULL) {

				if (attaquant->getNom() == proprio->getNom()) {

					// On offre 5 armee de bonus a l'attaquant
					attaquant->setNbArmeeTotal(attaquant->getNbArmeeTotal() + 5);
					attaquant->setNbArmeeDisponible(attaquant->getNbArmeeDisponible()
							+ 5);
				}
			}
		} else {
			paysDefense->setCouleurCourante(defenseur->couleur);
		}

		//**********
		if (paysAttaque->getNbArmee() == 0) {

			cout << "l'attaquant a perdu son territoire" << endl;
			defenseur->ajouterTerritoire(paysAttaque);
			attaquant->retirerTerritoire(paysAttaque);
			paysAttaque->setProprietaire(defenseur);
			paysAttaque->setCouleurOrigine(defenseur->couleur);
			paysAttaque->setNbArmee(1);
			paysDefense->setNbArmee(paysDefense->getNbArmee() - 1);

			// Test pour savoir si le contienent possede un proprietaire							
			Jeu* risk = Jeu::getInstance();

			Continent* continent = risk->getContinentByTerritoire(paysAttaque);

			Joueur* proprio = continent->getProprietaire(defenseur);

			// Si le continent possede un proprietaire et qu'il s'agit de l'attaquant
			if (proprio != NULL) {

				if (defenseur->getNom() == proprio->getNom()) {

					// On offre 5 armee de bonus a l'attaquant
					defenseur->setNbArmeeTotal(defenseur->getNbArmeeTotal() + 5);
					defenseur->setNbArmeeDisponible(defenseur->getNbArmeeDisponible()
							+ 5);
				}
			}

		} else {
			paysAttaque->setCouleurCourante(attaquant->couleur);
		}

		//paysAttaque->setCouleurCourante(attaquant->couleur);
	}

	cout << "fin combattre" <<endl;
}

// Affichage

void Combat::afficher() {
	cout<<endl;
	cout<<endl;
	cout<<"---------------------------------"<<endl;
	cout<<"Resulat du combat"<<endl;
	cout<<"---------------------------------"<<endl;
	cout<<"Attaquant  : "<< attaquant->getNom() << endl;
	cout<<"Territoire : "<< paysAttaque->getNom() <<endl;
	cout<<"Nombre armee(s) perdue(s) = "<< nbArmeePerduAttaque << endl;
	cout<<"Nombre armee(s) restante sur le territoire = "
			<< paysAttaque->getNbArmee() << endl;
	cout<<"Defenseur  : "<< defenseur->getNom() << endl;
	cout<<"Territoire : "<<paysDefense->getNom() << endl;
	cout<<"Nombre armee(s) perdue(s) = "<< nbArmeePerduDefense << endl;
	cout<<"Nombre armee(s) restante sur le territoire = "
			<<paysDefense->getNbArmee()<<endl;
	cout<<"---------------------------------"<<endl;
}

